import { Context } from 'koa'
import { insert, select, success, update } from '../utils'
import { devGit, onlineGit, testGit } from '../utils/git'
import { commitController } from './commit'

export class gitLogController {
  // 获取本地提交记录
  static async gitLogList(ctx: Context) {
    const localCommitLogs = await commitController.getCommitLogs(ctx, false)
    const remoteCommitLogs = await commitController.getRemoteCommitLogs(ctx, false)
    ctx.body = success(ctx, { localCommitLogs, remoteCommitLogs })
  }
  // 回滚分支
  static async gitResetHard(ctx: Context) {
    const { commitId, branchId, localLogs, remoteLastCommitId, targetBranch } = ctx.request.body as any
    if (branchId) {
      // 回滚当前分支
      const remoteCommitLogs = await commitController.getRemoteCommitLogs(ctx, false)
      if (
        remoteCommitLogs?.latest?.hash &&
        localLogs.every((item: any) => item.hash !== remoteCommitLogs?.latest?.hash)
      ) {
        throw new Error(`当前分支的远程有最新记录，请先拉取再回滚`)
      }
      await devGit[ctx.request.headers.nickname as any].gitResetHard(commitId)
      ctx.body = success(ctx)
    }
    if (targetBranch) {
      // 回滚远程分支：temp/master
      const remoteCommitLogs = await commitController.getRemoteCommitLogs(ctx, false)
      if (remoteCommitLogs?.latest?.hash !== remoteLastCommitId) {
        throw new Error(`当前远程分支${targetBranch}有最新记录，请先拉取再回滚`)
      }
      const git = targetBranch === 'temp' ? testGit : onlineGit
      await git.gitResetHard(commitId)
      ctx.body = success(ctx)
    }
  }
  // 合并commits
  static async mergeSameCommits(ctx: Context) {
    const { commitId, localLogs, commitMsg, branchId } = ctx.request.body as any

    // 回滚当前分支
    const remoteCommitLogs = await commitController.getRemoteCommitLogs(ctx, false)
    if (
      remoteCommitLogs?.latest?.hash &&
      localLogs.every((item: any) => item.hash !== remoteCommitLogs?.latest?.hash)
    ) {
      throw new Error(`当前分支的远程有最新记录，请先拉取再推送`)
    }
    await devGit[ctx.request.headers.nickname as any].gitMergeSameCommits(commitId, commitMsg)
    await update('branches', { id: branchId }, { has_unpush_code: 0 })
    ctx.body = success(ctx)
  }
  // 合并一条代码并推送
  static async mergeOneCode(ctx: Context) {
    const { targetBranch, branchId, latestHash } = ctx.request.body as any

    await devGit[ctx.request.headers.nickname as any].gitPush() // 推送当前代码
    await update('branches', { id: branchId }, { has_unpush_code: 0 })
    const [result]: [any, any] = (await select('branches', { id: branchId })) as [any, any]
    ;(ctx.request.body as any).curBranch = result[0].branch
    ;(ctx.request.body as any).develop_branch_id = targetBranch
    ;(ctx.request.body as any).isPull = true
    ;(ctx.request.body as any).canBack = true
    await devGit[ctx.request.headers.nickname as any].switchBranch(ctx) // 切换分支
    // 合并一条commit
    await devGit[ctx.request.headers.nickname as any]
      .cherryPick(latestHash)
      .then(async () => {
        await devGit[ctx.request.headers.nickname as any].gitPush() // 推送代码
      })
      .finally(async () => {
        // 切回分支
        ;(ctx.request.body as any).curBranch = targetBranch
        ;(ctx.request.body as any).develop_branch_id = branchId
        ;(ctx.request.body as any).isPull = false
        ;(ctx.request.body as any).canBack = false
        await devGit[ctx.request.headers.nickname as any].switchBranch(ctx)
        ctx.body = success(ctx)
      })
  }

  // 合并代码并推送
  static async mergeCode(ctx: Context) {
    const { targetBranch, branchId, localLogs } = ctx.request.body as any

    const remoteCommitLogs = await commitController.getRemoteCommitLogs(ctx, false)
    if (
      remoteCommitLogs?.latest?.hash &&
      localLogs.every((item: any) => item.hash !== remoteCommitLogs?.latest?.hash)
    ) {
      throw new Error(`当前分支还没有目标分支的最新commit，不能合并代码`)
    }
    await devGit[ctx.request.headers.nickname as any].gitPush() // 推送当前代码
    await update('branches', { id: branchId }, { has_unpush_code: 0 })
    const [result]: [any, any] = (await select('branches', { id: branchId })) as [any, any]
    ;(ctx.request.body as any).curBranch = result[0].branch
    ;(ctx.request.body as any).develop_branch_id = targetBranch
    ;(ctx.request.body as any).isPull = true
    ;(ctx.request.body as any).canBack = true
    await devGit[ctx.request.headers.nickname as any].switchBranch(ctx) // 切换分支
    // 合并分支
    await devGit[ctx.request.headers.nickname as any]
      .gitMerge(result[0].branch)
      .then(async () => {
        await devGit[ctx.request.headers.nickname as any].gitPush() // 推送代码
      })
      .finally(async () => {
        // 切回分支
        ;(ctx.request.body as any).curBranch = targetBranch
        ;(ctx.request.body as any).develop_branch_id = branchId
        ;(ctx.request.body as any).isPull = false
        ;(ctx.request.body as any).canBack = false
        await devGit[ctx.request.headers.nickname as any].switchBranch(ctx)
        ctx.body = success(ctx)
      })
  }

  // 发布环境: 测试、线上
  static async publishEnvironment(ctx: Context) {
    const { env } = ctx.request.body as any
    const nickname: string = ctx.request.headers.nickname as string
    if (env === 'master' && nickname !== 'admin') {
      throw new Error('只有管理员才能发布到master分支')
    }
    if (env === 'master') {
      onlineGit.gitPull()
    } else {
      testGit.gitPull()
    }
    ctx.body = success(ctx, {})
  }
}
